FreeRTOS 协同程序
协同程序是一种特殊的多任务编程方式,多个协同程序之间共用调用栈,且正在运行的协同程序不会被其他协程抢占(可以被任务和中断抢占),正在运行的协同程序只能自己主动让出CPU的使用权。要使用协同程序,需要将FreeRTOSConfig.h中的configUSE_CO_ROUTINES设为1。
FreeRTOS的协同程序采用switch-case实现,函数定义方式如下:
1void CoRoutineTask(CoRoutineHandle_t handle,UBaseType_t uxIndex)
2{
3 //协同程序中变量如果要保证值在下一次运行时仍有效,则必须为static
4 static const TickType_t delay = 1000 / portTICK_PERIOD_MS;
5
6 //协同程序必须以crSTART(handle)开始
7 crSTART(handle);
8
9 //协同程序主体
10 while(1)
11 {
12 /* 协同程序工作内容 */
13
14 //主动阻塞1000ms,让出CPU使用权
15 crDELAY(handle,delay);
16 }
17
18 //协同程序必须以crEND()结束
19 crEND()
20}使用vCoRoutineSchedule来调度协同程序,调用这个函数时,他会运行可运行的优先级最高的协同程序,当这个协同程序让出CPU时,vCoRoutineSchedule返回。需要不断的调用这个函数来进行协程的调度。
1#include <croutine.h>
2void vCoRoutineSchedule(void);使用xCoRoutineCreate来创建一个协程,它的第一个参数是协程函数,第二个参数是协程优先级,可以用同一个协程函数创建多个协程,第三个参数用来区分同一个函数创建的协程。
1#include <croutine.h>
2BaseType_t xCoRoutineCreate(crCOROUTINE_CODE pxCoRoutineCode,
3 UBaseType_t uxPriority,
4 UBaseType_t uxIndex );下面这个示例使用同一个函数创建了4个协程,协程函数打印uxIndex并阻塞1000ms:
1#include <stm32f4xx.h>
2#include <FreeRTOS.h>
3#include <task.h>
4#include <croutine.h>
5#include <uart.h>
6
7void coTask(CoRoutineHandle_t h,UBaseType_t uxIndex);
8void task(void* args);
9
10int main()
11{
12 //配置USART1
13 USART1_Config();
14 //创建协程
15 xCoRoutineCreate(coTask,0,0);
16 xCoRoutineCreate(coTask,0,1);
17 xCoRoutineCreate(coTask,0,2);
18 xCoRoutineCreate(coTask,0,3);
19 //创建任务,用于调度协程
20 xTaskCreate(task,"task1",configMINIMAL_STACK_SIZE,NULL,1,NULL);
21 //启动任务调度器
22 vTaskStartScheduler();
23}
24
25void task(void* args)
26{
27 while(1)
28 {
29 //运行优先级最高的协程,该协程让出时,函数返回
30 vCoRoutineSchedule();
31 }
32}
33
34
35void coTask(CoRoutineHandle_t handle,UBaseType_t uxIndex)
36{
37 //如果协程函数希望在阻塞后仍能保存变量的值,那么变量必须是static的
38 static const TickType_t delay = 1000 / portTICK_PERIOD_MS;
39
40 //协程函数必须以crSTART开始
41 crSTART(handle);
42
43 while(1)
44 {
45 //通过串口打印uxIndex
46 USART_printf(USART1,"coTask1 : %d\n",uxIndex);
47 //在协程中延时1000ms
48 crDELAY(handle,delay);
49 }
50
51 //协程函数必须以crEND结束
52 crEND();
53
54}